package edu.cmu.mism.dgjava.data.ui.composites.option;

import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

import edu.cmu.mism.dgjava.data.models.option.BinomialAmerican;
import edu.cmu.mism.dgjava.data.models.option.impl.OptionModelFactoryImpl;
import edu.cmu.mism.dgjava.utils.IDGConstants;
import edu.cmu.mism.dgjava.utils.SWTUtils;
import edu.cmu.mism.dgjava.views.Messages;

/**
 * 
 * @author Christian
 * 
 */
public class BinomialAmericanComposite extends OptionInputDataComposite {
	private static final String DEFAULT_TIME_TO_EXERCISE = "0.4167";
	private static final String DEFAULT_EX_PRICE = "50.00";
	private static final String DEFAULT_TREE_STEPS = "3";

	private Text _exTimeTxt;
	private Label _exTimeMessageLbl;

	private Text _exPriceTxt;
	private Label _exPriceMessageLbl;

	private Text _treeStepsTxt;
	private Label _treeStepsMessageLbl;

	@Override
	protected void createCustomControls(Composite parent) {
		GridData labelGd = new GridData(SWT.FILL, SWT.FILL, false, true);
		// labelGd.horizontalAlignment = GridData.HORIZONTAL_ALIGN_END;
		GridData hGd = new GridData(SWT.FILL, -1, true, false);

		Label exTimeLbl = SWTUtils
				.createLabel(parent, "Time to Expiration:", 1);
		// exTimeLbl.setLayoutData(labelGd);

		this._exTimeTxt = SWTUtils.createTextBox(parent, 1,
				SWTUtils.DEFAULT_TEXTBOX_WIDTH, -1, false);
		this._exTimeTxt.setText(DEFAULT_TIME_TO_EXERCISE);
		this._exTimeTxt.setLayoutData(hGd);
		this._exTimeMessageLbl = SWTUtils.createLabel(parent, "", 1);
		this._exTimeMessageLbl.setImage(JFaceResources
				.getImage(IDGConstants.DLG_IMG_TITLE_ERROR));

		Label exPriceLbl = SWTUtils.createLabel(parent,
				Messages.OptionDataView_exercise_price, 1);
		exPriceLbl.setLayoutData(labelGd);
		this._exPriceTxt = SWTUtils.createTextBox(parent, 1,
				SWTUtils.DEFAULT_TEXTBOX_WIDTH, -1, false);
		this._exPriceTxt.setText(DEFAULT_EX_PRICE);
		this._exPriceTxt.setLayoutData(hGd);
		this._exPriceMessageLbl = SWTUtils.createLabel(parent, "", 1);
		this._exPriceMessageLbl.setImage(JFaceResources
				.getImage(IDGConstants.DLG_IMG_TITLE_ERROR));

		Label treeStepsLbl = SWTUtils.createLabel(parent, "Tree Steps:", 1);
		treeStepsLbl.setLayoutData(labelGd);

		this._treeStepsTxt = SWTUtils.createTextBox(parent, 1,
				SWTUtils.DEFAULT_TEXTBOX_WIDTH, -1, false);
		this._treeStepsTxt.setLayoutData(hGd);
		this._treeStepsTxt.setText(DEFAULT_TREE_STEPS);
		this._treeStepsMessageLbl = SWTUtils.createLabel(parent, "", 1);
		this._treeStepsMessageLbl.setImage(JFaceResources
				.getImage(IDGConstants.DLG_IMG_TITLE_ERROR));
		

	}

	@Override
	public Object getDataObject() {
		BinomialAmerican data = OptionModelFactoryImpl.eINSTANCE
				.createBinomialAmerican();
		data.setExercisePrice(Double.parseDouble(this._exPriceTxt.getText()));
		data.setTreeSteps(Integer.parseInt(this._treeStepsTxt.getText()));
		data.setType(getOptionBaseType());
		data.setTimeToExpire(Double.parseDouble(this._exTimeTxt.getText()));

		return data;
	}
	
	/**
	 * Hook up modify listener to observe modification event and validate user's
	 * input
	 */
	protected void hookupModifyListener() {
		this._exPriceTxt.addModifyListener(_validator);
		this._exTimeTxt.addModifyListener(_validator);
		this._treeStepsTxt.addModifyListener(_validator);
	}

	@Override
	protected void validate() {
		if (this._exTimeTxt.getText() == null
				|| this._exTimeTxt.getText().length() == 0) {
			this._exTimeMessageLbl
					.setToolTipText("Exercise time can not be empty");
			this._exTimeMessageLbl.setVisible(true);
		} else {
			try {
				Double.valueOf(this._exTimeTxt.getText()
						.trim());
				this._exTimeMessageLbl.setToolTipText(null);
				this._exTimeMessageLbl.setVisible(false);
				
			} catch (NumberFormatException e) {
				this._exTimeMessageLbl
						.setToolTipText("Exercise time must be a valid decimal number");
				this._exTimeMessageLbl.setVisible(true);
			}
		}
		
		if (this._exPriceTxt.getText() == null
				|| this._exPriceTxt.getText().length() == 0) {
			this._exPriceMessageLbl
					.setToolTipText("Exercise price can not be empty");
			this._exPriceMessageLbl.setVisible(true);
		} else {
			try {
				Double.valueOf(this._exPriceTxt.getText()
						.trim());
				this._exPriceMessageLbl.setToolTipText(null);
				this._exPriceMessageLbl.setVisible(false);
				
			} catch (NumberFormatException e) {
				this._exPriceMessageLbl
						.setToolTipText("Exercise price must be a decimal number");
				this._exPriceMessageLbl.setVisible(true);
			}
		}
		
		if (this._treeStepsTxt.getText() == null
				|| this._treeStepsTxt.getText().length() == 0) {
			this._treeStepsMessageLbl
					.setToolTipText("Tree step must be specified");
			this._treeStepsMessageLbl.setVisible(true);
		} else {
			try {
				Integer.valueOf(this._treeStepsTxt.getText()
						.trim());
				this._treeStepsMessageLbl.setToolTipText(null);
				this._treeStepsMessageLbl.setVisible(false);
				
			} catch (NumberFormatException e) {
				this._treeStepsMessageLbl
						.setToolTipText("Tree step given must be a valid integer");
				this._treeStepsMessageLbl.setVisible(true);
			}
		}
	}
}
